/*
 * @Author: Jiraiya
 * @Date: 2020-05-29 16:18:59
 * @LastEditors: Jiraiya
 * @LastEditTime: 2020-05-29 19:17:54
 * @Description: 
 */ 

/**
 * @description: 防抖函数：超过一定的暂停时间才会执行,例如输入框实时检索
 * @param {type} 
 * @return: 
 */
function debounce(fn, delay = 500){
    let timer = null;
    return function(){
        if(timer) clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this, arguments);
        }, delay);
    }
}






/**
 * @description: 节流函数：任务在固定时间内只执行一次，scroll滚动或者动画
 * @param {type} 
 * @return: 
 */
function throttle(fn, delay=500){
    let timer = null;
    return function(){
        if(timer) return;
        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null;
        }, delay);
    }
}





/**
 * @description: 对象深拷贝
 * @param {type} 
 * @return: 
 */

function objectDeepClone(obj){
    const res = Array.isArray(obj) ? [] : {};
    const keys = [...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj)];
    keys.map(key => {
        if(obj[key] === null || typeof obj[key] !== 'object'){
            res[key] = obj[key];
        }else{
            res[key] = objectDeepClone(obj[key]);
        }
    })
    return res;
}






/**
 * @description: 洗牌算法
 * @param {type} 
 * @return: 
 */
function arrShuffle(arr){
    if(!Array.isArray(arr)){
        throw new Error('arguments[0] must is array');
    }
    let m = arr.length;
    while(m > 1){
        const index = Math.floor(Math.random() * m--);
        [arr[index], arr[m]] = [arr[m], arr[index]];
    }
    return arr;
}






/**
 * @description: 多维数组展开
 * @param {type} 
 * @return: 
 */
function arrFlat(arr, deep){
    let result = [];
    if(deep === 0) return arr;
    deep--;
    arr.forEach((e) => {
        result = result.concat(Array.isArray(e) ? arrFlat(e, deep) : e);
    })
    return result;
}

function arrFlat(arr, deep){
    if(deep === 0) return arr;
    deep--;
    return [].concat(...arr.map(e => {
        return Array.isArray(e) ? arrFlat(e, deep) : e;
    }))
}

function arrFlat(arr, deep){
    if(deep === 0) return arr;
    deep--;
    return arr.reduce((res, e) =>{
        return res.concat(Array.isArray(e) ? arrFlat(e, deep) : e);
    }, [])
}

function arrFlat(arr, deep){
    let res = [];
    arr.forEach(e => {
        if(Array.isArray(e) && deep > 0){
            res = res.concat(arrFlat(e), deep - 1)
        }else{
            res.push(e);
        }
    })
    return res;
}









/**
 * @description: 函数柯里化
 * @param {type} 
 * @return: 
 */
function carry(fn, n){
    const result = (...args) => args.length === n ? fn(...args) :
    (...nextArgs) => result(...[...args, ...nextArgs]);
    return result;
}




/**
 * @description: compose
 * @param {type} 
 * @return: 
 */
function compose(...arrFn){
    const len = arrFn.length;
    if(len === 0) return args => args;
    if(len === 1) return arrFn[0];
    return arrFn.reduce((a, b)=>{
        return (...args) => a(b(...args));
    })
}